﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESBasic.ObjectManagement;
using ESBasic.Emit.DynamicBridge;
using ESPlus.Application.Basic.Passive;
using ESBasic.ObjectManagement.Forms;
using ESBasic;
using ESPlus.Rapid;
using ESFramework.Engine.ContractStyle.Stream;
using ESFramework.Engine.Tcp.Passive;
using ESFramework.Demos.Core;
using ESPlus.Application.Basic;
using ESPlus.Application.Group;
using ESPlus.Application.Group.Passive;
using ESPlus.Application.CustomizeInfo;
using ESPlus.Application.FileTransfering;
using ESPlus.Application.P2PSession.Passive;
using ESPlus.Application.CustomizeInfo.Passive;
using ESPlus.FileTransceiver;
using Chat.Forms;
using System.Data.SqlClient;
using OMCS.Passive;

namespace Chat
{
    public partial class MainForm : Form, ICustomizeHandler
    {
        private string userID;
        private RapidPassiveEngine rapidPassiveEngine;
        private FormManager<string, ChatForm> chatFormManager = new FormManager<string, ChatForm>();
        private FormManager<string, GroupForm> groupFormManager = new FormManager<string, GroupForm>();

        private IMultimediaManager multimediaManager;

        private IBasicOutter basicOutter;
        //private IGroupOutter groupOutter;
        private List<string> listgroup = new List<string>();
        private object lockObject = new object();
        //private GroupTools groupTools = null;

        public string UserID
        {
            get{ return userID;}
            set{ userID = value;}
            }

        public MainForm()
        {
            InitializeComponent();
        }

        #region Initialize
        public void Initialize(IMultimediaManager mgr, RapidPassiveEngine engine)
        {
            this.multimediaManager = mgr;
            this.multimediaManager.CameraDeviceIndex = 0;
            this.multimediaManager.MicrophoneDeviceIndex = 0;
            this.multimediaManager.SpeakerIndex = 0;
            this.multimediaManager.ChannelMode = OMCS.Passive.ChannelMode.P2PChannelFirst;
            this.multimediaManager.CameraEncodeQuality = 3;

            this.userID = engine.CurrentUserID;
            this.rapidPassiveEngine = engine;

            this.basicOutter = engine.BasicOutter;

            this.listgroup = GetGroupName(engine.CurrentUserID);
            //this.groupChatControl1.Initialize(this.groupID, engine);

            //预订断线事件
            this.rapidPassiveEngine.ConnectionInterrupted += new CbGeneric(rapidPassiveEngine_ConnectionInterrupted);
            //预订重连开始事件
            this.rapidPassiveEngine.ConnectionRebuildStart += new CbGeneric(rapidPassiveEngine_ConnectionRebuildStart);
            //预订重连成功并重新登陆事件
            this.rapidPassiveEngine.RelogonCompleted += new CbGeneric<LogonResponse>(rapidPassiveEngine_RelogonCompleted);
            //预订好友上线的事件
            this.rapidPassiveEngine.FriendsOutter.FriendConnected += new CbGeneric<string>(FriendOutter_FriendConnected);
            //预订好友下线的事件
            this.rapidPassiveEngine.FriendsOutter.FriendOffline += new CbGeneric<string>(FriendOutter_FriendOffline);
            //预订自己被踢出掉线的事件
            this.rapidPassiveEngine.BasicOutter.BeingKickedOut += new CbGeneric(BasicOutter_BeingKickedOut);
            //预订自己被挤掉掉线的事件
            this.rapidPassiveEngine.BasicOutter.BeingPushedOut += new CbGeneric(BasicOutter_BeingPushedOut);

            //预订收到了来自发送方发送文件的请求事件
            this.rapidPassiveEngine.FileOutter.FileRequestReceived += new ESPlus.Application.FileTransfering.CbFileRequestReceived(FileOutter_FileRequestReceived);
            //预订接收方回复了同意/拒绝接收文件时的事件
            this.rapidPassiveEngine.FileOutter.FileResponseReceived += new CbGeneric<TransferingProject, bool>(FileOutter_FileResponseReceived);

            //预订P2P Channel创建成功事件
            this.rapidPassiveEngine.P2PController.P2PChannelOpened += new CbGeneric<ESPlus.Application.P2PSession.Passive.P2PChannelState>(P2PController_P2PChannelOpened);
            //预订P2P Channel创建关闭时的事件
            this.rapidPassiveEngine.P2PController.P2PChannelClosed += new CbGeneric<ESPlus.Application.P2PSession.Passive.P2PChannelState>(P2PController_P2PChannelClosed);

            this.toolStripLabel_loginfo.Text = string.Format("当前登录：{0}", this.userID);
            this.toolStripLabel_state.Text = "连接状态：正常";
            this.InitializeFriends();
            //this.InitializeGroupmates();
            this.InitializeGroups();
        }

        //获取组名
        public List<string> GetGroupName(string userID)
        {
            //string result = "";
            List<string> result = new List<string>();
            string ConnectionString = "Data Source=QC-PC;Initial Catalog=Chat;Persist Security Info=True;User ID=sa;Password=123456";
            string MySQL = "Select GroupsName From Groups Where Name='" + userID + "'";
            SqlConnection MyConnection = new SqlConnection(ConnectionString);
            MyConnection.Open();
            SqlCommand MyCommand = new SqlCommand(MySQL, MyConnection);
            SqlDataReader MyReader = MyCommand.ExecuteReader();
            while (MyReader.Read())
            {
                //list.Add(MyReader.GetString(0).Trim());
               // this.listView2.Items.Add(MyReader.GetString(0).Trim(), 0);
                result.Add(MyReader.GetString(0).Trim());
            }
            return result;
        }

        private void InitializeGroups()
        {
            foreach (string groupID in listgroup)
            {
                if (!this.ContainsGroup(groupID))
                {
                    this.AddGroup(groupID);
                }
            }
        }

        private bool ContainsGroup(string GroupID)
        {
            foreach(ListViewItem item in this.listView2.Items)
            {
                if(item.Text == GroupID)
                {
                    return true;
                }
            }
            return false;
        }


        //listView2 Add
        private void AddGroup(string GroupID)
        {
            lock (this.lockObject)
            {
                if (this.ContainsGroup(GroupID))
                {
                    return;
                }
                this.listView2.Items.Add(GroupID, 1);
            }
        }

        void P2PController_P2PChannelClosed(ESPlus.Application.P2PSession.Passive.P2PChannelState state)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<P2PChannelState>(this.P2PController_P2PChannelClosed), state);
            }
            else
            {
                ChatForm form = this.chatFormManager.GetForm(state.DestUserID);
                if (form != null)
                {
                    form.ShowP2PChannelState(this.rapidPassiveEngine.P2PController.GetP2PChannelState(state.DestUserID));
                }
            }
        }

        void P2PController_P2PChannelOpened(ESPlus.Application.P2PSession.Passive.P2PChannelState state)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<P2PChannelState>(this.P2PController_P2PChannelOpened), state);
            }
            else
            {
                ChatForm form = this.chatFormManager.GetForm(state.DestUserID);
                if (form != null)
                {
                    form.ShowP2PChannelState(this.rapidPassiveEngine.P2PController.GetP2PChannelState(state.DestUserID));
                }
            }
        }

        //发送方收到 接收方(同意或者拒绝 接收文件)的回应时的处理 
        void FileOutter_FileResponseReceived(TransferingProject transferingProject, bool agreeRecive)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<TransferingProject, bool>(this.FileOutter_FileResponseReceived), transferingProject, agreeRecive);
            }
            else
            {
                ChatForm form = this.chatFormManager.GetForm(transferingProject.DestUserID);
                if (form != null)
                {
                    form.Focus();
                    form.OnFileResponse(transferingProject, agreeRecive);
                }
            }
        }

        //当收到对方文件时的处理
        void FileOutter_FileRequestReceived(string fileID, string senderID, string fileName, ulong totalSize, ESPlus.FileTransceiver.ResumedProjectItem resumedProjectItem, string comment)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<string, string, string, ulong, ResumedProjectItem, string>(this.FileOutter_FileRequestReceived), fileID, senderID, fileName, totalSize, resumedProjectItem, comment);
            }
            else
            {
                ChatForm form = this.chatFormManager.GetForm(senderID);
                if (form == null)
                {
                    form = new ChatForm(senderID,this.rapidPassiveEngine,this.multimediaManager);
                    this.chatFormManager.Add(form);
                    form.Show();
                }
                form.Focus();
                form.OnFileRequest(fileID, senderID, fileName);
            }
        }

        private void InitializeFriends()
        {
            //List<string> list = this.rapidPassiveEngine.BasicOutter.GetAllOnlineUsers();

            //获取所有在线好友列表
            List<string> list1 = this.rapidPassiveEngine.FriendsOutter.GetAllOnlineFriends();
            //获取好友列表
            List<string> list2 = this.rapidPassiveEngine.FriendsOutter.GetFriends(null);

            foreach (string friendID in list2)
            {
                this.listView1.Items.Add(friendID, 0);
            }
            //设置在线好友的字体色彩属性
            SetOnLineFriend(list1, listView1, Color.Red);
        }

        #region ListViewContains
        private bool ListViewContains(string userID)
        {
            for (int i = 0; i < this.listView1.Items.Count; i++)
            {
                if (this.listView1.Items[i].Text == userID)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region SetOnLineFriend
        private void SetOnLineFriend(List<string> list, ListView listview, Color color )
        {
            foreach (string ID in list)
            {
                for (int i = 0; i < listview.Items.Count; i++)
                {
                    if (listview.Items[i].Text == ID)
                    {
                        listview.Items[i].ForeColor = color;
                    }
                }
            }
        }
        #endregion

        #region SetOnLineFriend
        private void SetOnLineFriend(string friendID, ListView listview, Color color)
        {
            for (int i = 0; i < listview.Items.Count; i++)
            {
                if (listview.Items[i].Text == friendID)
                {
                    listview.Items[i].ForeColor = color;
                }
            }
        }
        #endregion

        #endregion

        #region IBasicOutter的事件
        #region 被挤掉线
        void BasicOutter_BeingPushedOut()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric(this.BasicOutter_BeingPushedOut), null);
            }
            else
            {
                this.OnDisconnected();
                this.toolStripLabel_state.Text = "连接状态：断开！";
                this.toolStripLabel_state.ForeColor = Color.Red;
            }
        }
        #endregion

        #region 被踢出
        void BasicOutter_BeingKickedOut()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric(this.BasicOutter_BeingKickedOut), null);
            }
            else
            {
                this.OnDisconnected();
                this.toolStripLabel_state.Text = "连接状态：断开！";
                this.toolStripLabel_state.ForeColor = Color.Red;
                MessageBox.Show("您已经被提出！");
            }
        } 
        #endregion
        #endregion

        #region FriendOutter事件
        #region 好友下线
        void FriendOutter_FriendOffline(string friendID)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<string>(this.FriendOutter_FriendOffline), friendID);
            }
            else
            {
                ListViewItem target = null;
                foreach (ListViewItem item in this.listView1.Items)
                {
                    if (item.Text == friendID)
                    {
                        target = item;
                        break;
                    }
                }

                if (target != null)
                {
                    //this.listView1.Items.Remove(target);
                    SetOnLineFriend(target.Text, listView1, Color.Black);
                }

                ChatForm form = this.chatFormManager.GetForm(friendID);
                if (form != null)
                {
                    form.SelfOrFriendOffline();
                }
            }
        }
        #endregion

        #region 好友上线
        void FriendOutter_FriendConnected(string friendID)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<string>(this.FriendOutter_FriendConnected), friendID);
            }
            else
            {
                //if (!this.ListViewContains(friendID))
                //{
                //    this.listView1.Items.Add(friendID, 0);
                //}
                SetOnLineFriend(friendID, listView1, Color.Red);
            }
        }
        #endregion
        #endregion

        #region 网络状态变化事件
        #region 断线 重连 重新登录完成事件
        void rapidPassiveEngine_RelogonCompleted(LogonResponse relogonResult)
        {
            //如果在 重新登录的时候，数据库的密码 修改了，则这里relogonResult会返回登录失败 
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<LogonResponse>(this.rapidPassiveEngine_RelogonCompleted), relogonResult);
            }
            else
            {
                if (relogonResult.LogonResult != LogonResult.Succeed)
                {
                    return;
                }
                this.toolStripLabel_state.Text = "连接状态：正常（重连成功）";
                this.toolStripLabel_state.ForeColor = Color.Black;

                this.InitializeFriends();
            }
        }
        #endregion

        #region 重连开始事件
        void rapidPassiveEngine_ConnectionRebuildStart()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbSimple(this.rapidPassiveEngine_ConnectionRebuildStart), null);
            }
            else
            {
                this.toolStripLabel_state.Text = "连接状态：断开，重连中......";
                this.toolStripLabel_state.ForeColor = Color.Red;
            }
        }
        #endregion

        #region 断线事件
        void rapidPassiveEngine_ConnectionInterrupted()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbSimple(this.rapidPassiveEngine_ConnectionInterrupted), null);
            }
            else
            {
                this.OnDisconnected();
                this.toolStripLabel_state.Text = "连接状态：断开";
                this.toolStripLabel_state.ForeColor = Color.Red;
            }
        }
        #endregion

        private void OnDisconnected()
        {
            this.listView1.Clear();

            foreach (ChatForm form in this.chatFormManager.GetAllForms())
            {
                form.SelfOrFriendOffline();
            }
        }
        #endregion



        #region ICustomizeHandler 实现 -- 处理接收到的自定义信息
        /// <summary>
        ///  处理消息,如果sourceUserID为null， 则表示是服务端发送过来的消息；如果sourceUserID不为null， 则表示是其他客户端发送过来的消息
        /// </summary>       
        public void HandleInformation(string sourceUserID, int informationType, byte[] info)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<string, int, byte[]>(this.HandleInformation), sourceUserID, informationType, info);
            }
            else
            {
                //私聊
                if (informationType == InformationTypes.Chat)
                {
                    ChatForm form = this.chatFormManager.GetForm(sourceUserID);
                    if (form == null)
                    {
                        form = new ChatForm(sourceUserID,this.rapidPassiveEngine, this.multimediaManager);
                        this.chatFormManager.Add(form);
                        form.Show();
                    }
                    form.Focus();

                    ESFramework.Demos.Core.TextChatContract contract = (ESFramework.Demos.Core.TextChatContract)ESBasic.Helpers.SerializeHelper.DeserializeBytes(info, 0, info.Length);
                    form.ShowOtherTextChat(sourceUserID, contract);
                }

                //群聊
                //if (informationType == GroupInformationTypes.GroupChat)
                //{
                //    GroupForm form = this.groupFormManager.GetForm(sourceUserID);
                //    if (form == null)
                //    {
                //        form = new GroupForm("Home", this.rapidPassiveEngine, this.multimediaManager);
                //        this.groupFormManager.Add(form);
                //        form.Show();
                //    }
                //    form.Focus();
                //}
                    
                //if (informationType == ESFramework.Demos.Core.GroupInformationTypes.SomeoneJoinGroup)
                //{
                //    this.OnGroupmateConnected(System.Text.UTF8Encoding.UTF8.GetString(info));
                //    return;
                //}
                //if (informationType == ESFramework.Demos.Core.GroupInformationTypes.SomeoneQuitGroup)
                //{
                //    this.OnGroupmateOffline(System.Text.UTF8Encoding.UTF8.GetString(info));
                //    return;
                //}

                #region//视频请求
                if (informationType == InformationTypes.VideoRequest)
                {
                    ChatForm form = this.GetChatForm(sourceUserID);
                    if (form.HaveVideo)
                    {
                        return;
                    }
                    form.OpenVideoViewer(ViewerType.VideoRequest, false);
                    return;
                }
                #endregion

            }
                
        }

        #region GetChatFrom
        private ChatForm GetChatForm(string friendID)
        {
            ChatForm form = this.chatFormManager.GetForm(friendID);
            if (form == null)
            {
                this.CreateChatForm(friendID);
                form = this.chatFormManager.GetForm(friendID);
            }
            return form;
        }
        #endregion

        #region
        private void CreateChatForm(string friendID)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<string>(this.CreateChatForm), friendID);
            }
            else
            {
                ChatForm form = new ChatForm(friendID, this.rapidPassiveEngine, this.multimediaManager);
                this.chatFormManager.Add(form);
                form.Show();
            }
        }
        #endregion

        public byte[] HandleQuery(string sourceUserID, int informationType, byte[] info)
        {
            return null;
        }

        #endregion

        #region 双击鼠标弹出聊天窗口
        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Left)
            {
                return;
            }

            ListViewHitTestInfo info = this.listView1.HitTest(e.Location);
            if (info.Item != null)
            {
                ChatForm form = this.chatFormManager.GetForm(info.Item.Text);
                if (form == null)
                {
                    form = new ChatForm(info.Item.Text,this.rapidPassiveEngine, this.multimediaManager);
                    this.chatFormManager.Add(form);
                    form.Show();
                }
                form.Focus();
            }

        }
        #endregion

        private void listView2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Left)
            {
                return;
            }

            ListViewHitTestInfo info = this.listView2.HitTest(e.Location);
            if (info.Item != null)
            {
                GroupForm form = this.groupFormManager.GetForm(info.Item.Text);
                if (form == null)
                {
                    form = new GroupForm(info.Item.Text, this.rapidPassiveEngine, this.multimediaManager);
                    this.groupFormManager.Add(form);
                    form.Show();
                }
                form.Focus();
            }

        }
    }
}
